home *** CD-ROM | disk | FTP | other *** search
- #ifdef _LILA_ENTE_
- ############################################################################
- ## ##
- ## This is ADT 2.5, a user friendly frontend for all Aminet FTP sites. It ##
- ## can be compiled easily on any UNIX flavor and AmigaDOS. Under UNIX, ##
- ## compile it using the command ##
- ## ##
- ## sh adt.c (you may append flags, e.g. sh adt.c -DNO_FTP) ##
- ## ##
- ## or use simply type make (your current dir should be where adt.c is) ##
- ## ##
- ## Improvements of adt.c version 2.5: ##
- ## - fixed hanging FTP connections with "us.aminet.net" ##
- ## ##
- ## Urban Mueller <umueller@aminet.net> ##
- ## ##
- ## See adt.c.readme for further notes ##
- ## ##
- ############################################################################
-
- libs="-lcurses -ltermcap"
- for i in /usr/lib/libsocket* ; do if [ -r $i ] ; then # Kludge for systems
- libs="$libs -lsocket -lnsl" ; break # with bash as /bin/sh
- fi ; done # like NetBSD or Linux
-
- echo "Compiling... if all compiles OK, type ./adt to start"
- echo ""
- echo cc -O -s -o adt $* $0 $libs
- exec cc -O -s -o adt $* $0 $libs
- exit
- #endif
-
- #include <stdio.h>
-
- #ifdef AMIGA
- # define getchr getch
- # define makedir(x,y) mkdir(x)
- # define popen(x,y) stdout
- # define pclose(x)
- # define sleep(x)
- # define COPYCMD "copy"
- # define CURDIR "\"\""
- # define TEMPPATH "t:"
- # define NO_FTP
- # define NO_FIND_CLIENT
- # define _system(x) puts(x)
- #else
- # define getchr getchar
- # define makedir(x,y) mkdir(x,y)
- /* # define COPYCMD "cp" DO NOT USE COPY FOR DOWNLOAD VIA NFS */
- # define COPYCMD "ln -s" /* use softlink instead of, and cp manually */
- # define CURDIR "."
- # define TEMPPATH "/tmp/"
- #endif
-
- #ifdef NO_FTP
- # define NO_BUILTIN_FTP
- # define NO_EXTERNAL_FTP
- #endif
-
- #ifdef NO_BUILTIN_FTP
- # ifdef NO_FIND_CLIENT
- # define NO_TCP_UTILITY
- # endif
- #else /* !NO_BUILTIN_FTP */
- # define NO_EXTERNAL_FTP
- #endif
-
- /*---------------------------------INCLUDES---------------------------------*/
- #define _INCLUDE_POSIX_SOURCE
-
- #ifndef AMIGA
- # include <sys/types.h>
-
- # ifdef DEBUG
- # include <stdlib.h>
- # include <unistd.h>
- # include <string.h>
- # include <sys/param.h>
- # include <sys/stat.h>
- # endif
-
- # ifndef NO_EXTERNAL_FTP
- # include <sys/stat.h>
- # endif
-
- # ifndef NO_TCP_UTILITY
- # include <sys/file.h>
- # include <stdio.h>
- # include <netdb.h>
- # include <sys/socket.h>
- # include <netinet/in.h>
- # include <arpa/inet.h>
- # endif
- #endif
-
- #ifndef NO_CURSES
- # include <curses.h>
- #endif
-
- #include <signal.h>
- /*---------------------------------GLOBALS-----------------------------------*/
-
- #define E_FILE 20
- #define E_DIR 10
- #define E_DESC 44
-
- #define K_CTRL -'@'
-
- struct adt_entry {
- long time;
- long size;
- long readmesize;
- short version;
- char readmelen;
- char tagged;
- char osversion;
- char status;
- char file[E_FILE + 1];
- char dir[E_DIR + 1];
- char desc[E_DESC + 1];
- };
- #define ENTRY struct adt_entry
-
- #define STATUS_LOCAL 0
- #define STATUS_REMOTE 1
-
-
- struct adt_list {
- ENTRY **list;
- char *(*disp) ();
- int mem;
- int num;
- int offset;
- int current;
- char type;
- char top;
- char *sel;
- char *sort;
- char *cmds;
- };
- #define LIST struct adt_list
-
-
- struct adt_transfer {
- char *name;
- char *text;
- int (*init) ();
- };
- #define TRANSFER struct adt_transfer
-
- extern TRANSFER TransferTypes[];
-
-
- LIST AllFiles, VisibleFiles, Marked, Alternate;
- LIST *File = &AllFiles, *Vis = &VisibleFiles, *Mark = &Marked, *Alt = &Alternate;
-
- int Dispmode;
- int Width = 80, Height = 25;
- int LastCall;
- char *NoFilesString = "No files available";
- char HomeDir[250];
- char UserName[50] = "user";
- char ConfigFile[200] = ".adtrc";
- char *FindDesc = "Performing local case insensitive substring search";
- char GotComplete, GotLocal, GotRecent;
- char Flat, Readme, Silent, Path[250], Action;
- char InitialSetup;
- char Connected;
- char MaskSIGINT, GotSIGINT;
-
- int (*disp_init) ();
- int (*disp_cleanup) ();
- int (*disp_choice) ();
- int (*disp_mainloop) ();
- int (*disp_report) ();
- int (*disp_status) ();
- int (*disp_confirm) ();
- int (*disp_more) ();
- int (*disp_getchar) ();
- int (*disp_refresh) ();
- int (*disp_clear) ();
- char *(*disp_inputstr) ();
-
- int (*trans_options) ();
- int (*trans_connect) ();
- int (*trans_remopen) ();
- int (*trans_download) ();
- int (*trans_disconnect) ();
- int (*trans_close) ();
-
- /*----------------------------main exit point--------------------------------*/
- int exit_adt(err)
- char *err;
- {
- if (disp_cleanup)
- disp_cleanup();
-
- if (trans_close)
- trans_close();
-
- if (err)
- puts(err);
-
- exit(err ? 20 : 0);
-
- return 0;
- }
-
- /*--------------------------quick entry allocator----------------------------*/
- #define CHUNKALLOC 100
-
- struct EntryChunk {
- struct EntryChunk *next;
- ENTRY chunks[CHUNKALLOC];
- };
- #define CHUNK struct EntryChunk
-
- int InCount;
- CHUNK *EntryChunk, *ChunkList;
-
- char *salloc(len)
- int len;
- {
- char *t;
-
- if (!(t = (char *) malloc(len)))
- exit_adt("out of memory\n");
-
- return t;
- }
-
-
- ENTRY *e_alloc()
- {
- if (!InCount) {
- InCount = CHUNKALLOC;
- EntryChunk = (CHUNK *) salloc(sizeof(CHUNK));
- EntryChunk->next = ChunkList;
- ChunkList = EntryChunk;
- }
- return EntryChunk->chunks + --InCount;
- }
-
- int e_add(l, e)
- LIST *l;
- ENTRY *e;
- {
- ENTRY **oldlist;
- int i;
-
- if (!l->mem) {
- l->mem = 100;
-
- l->list = (ENTRY **) salloc(l->mem * sizeof(ENTRY *));
- }
- if (l->num == l->mem) {
- oldlist = l->list;
-
- l->list = (ENTRY **) salloc(2 * l->mem * sizeof(ENTRY *));
-
- for (i = 0; i < l->num; i++)
- l->list[i] = oldlist[i];
-
- l->mem *= 2;
- free(oldlist);
- }
- l->list[l->num++] = e;
- return 0;
- }
-
- int l_reset(l)
- LIST *l;
- {
- if (l->list)
- free(l->list);
- l->list = 0;
- l->mem = 0;
- l->num = 0;
- l->current = 0;
- return 0;
- }
-
- int l_store()
- {
- int i;
- ENTRY **e1, **e2;
-
- if (Alt->list)
- free(Alt->list);
-
- if (Vis->mem)
- Alt->list = (ENTRY **) salloc(Vis->mem * sizeof(ENTRY *));
-
- for (i = Vis->num - 1, e1 = Vis->list, e2 = Alt->list; i >= 0; i--)
- *e2++ = *e1++;
-
- Alt->list = Vis->list;
- Alt->num = Vis->num;
- Alt->mem = Vis->mem;
- Alt->offset = Vis->offset;
- Alt->current = Vis->current;
- Alt->sel = Vis->sel;
- Alt->sort = Vis->sort;
-
- return 0;
- }
-
- int e_freeall()
- {
- CHUNK *c, *next;
-
- l_reset(Alt);
- l_reset(Mark);
- l_reset(Vis);
- l_reset(File);
-
- for (c = ChunkList; c; c = next) {
- next = c->next;
- free(c);
- }
- ChunkList = 0;
- InCount = 0;
- GotComplete = GotLocal = GotRecent = 0;
-
- return 0;
- }
-
- /*-------------------------string funcs for portability----------------------*/
- int mystrlen(s)
- char *s;
- {
- int n = 0;
-
- while (*s++)
- n++;
- return n;
- }
-
- int mystrncpy(s1, s2, n)
- char *s1, *s2;
- int n;
- {
- while (*s2 && n--)
- *s1++ = *s2++;
-
- *s1++ = 0;
-
- return 0;
- }
-
- char *mystrcpy(s1, s2)
- char *s1, *s2;
- {
- char *t = s1;
-
- while ((*s1++ = *s2++));
-
- return t;
- }
-
- int mystrcmp(s1, s2)
- char *s1, *s2;
- {
- while (*s1 == *s2 && *s1)
- s1++, s2++;
-
- return *s1 - *s2;
- }
-
- #define LOWER(x) (x<='Z' && x>='A' ? x-'A'+'a' : x)
-
- int mystricmp(s1, s2)
- char *s1, *s2;
- {
- while (LOWER(*s1) == LOWER(*s2) && *s1)
- s1++, s2++;
-
- return LOWER(*s1) - LOWER(*s2);
- }
-
- int mystrncmp(s1, s2, n)
- char *s1, *s2;
- int n;
- {
- while (n && *s1 && *s1 == *s2)
- s1++, s2++, n--;
-
- return n != 0 && *s1 - *s2;
- }
-
- int mystrnicmp(s1, s2, n)
- char *s1, *s2;
- int n;
- {
- while (n && *s1 && LOWER(*s1) == LOWER(*s2))
- s1++, s2++, n--;
-
- return n != 0 && LOWER(*s1) - LOWER(*s2);
- }
-
- char *myfgets(buf, len, file)
- char *buf;
- int len;
- FILE *file;
- {
- char *t, *r;
-
- if ((r = fgets(buf, len, file))) {
- for (t = buf; *t && *t != '\n'; t++);
-
- *t = 0;
- }
- return r;
- }
-
- char *mystristr(str1, str2)
- char *str1, *str2;
- {
- char c = LOWER(*str1), l = strlen(str1);
-
- for (;;) {
- while (*str2 && LOWER(*str2) != c)
- str2++;
-
- if (!*str2)
- break;
-
- if (!mystrnicmp(str1, str2, l))
- return str2;
-
- str2++;
- }
-
- return 0;
- }
-
- long myatoi(s)
- char *s;
- {
- long r = 0;
-
- while (*s && *s >= '0' && *s <= '9')
- r = 10 * r + *s++ - '0';
-
- return r;
- }
-
- char rdmbuf[200];
-
- char *
- get_readme(e)
- ENTRY *e;
- {
- strcpy(rdmbuf,e->file);
- strcpy(rdmbuf+strlen(rdmbuf)-e->readmelen, ".readme");
- return rdmbuf;
- }
-
- #define MYMIN(x,y) ((x)<(y) ? (x) : (y))
- #define MYMAX(x,y) ((x)>(y) ? (x) : (y))
-
-
- #ifdef AMIGA
-
- char *glob_path (buf)
- char *buf;
- {
- return buf;
- }
-
- #else
-
- #include <pwd.h>
-
- char *glob_path (buf)
- char *buf;
- {
- short bindex = 1;
- struct passwd pw_info, *pw;
- char buf2[300];
-
- if (buf[0] != '~')
- return buf;
-
- pw_info.pw_dir = (char *) getenv("HOME");
- if (buf[1] && buf[1] != '/') {
- char username[128];
-
- while (buf[bindex] && buf[bindex] != '/')
- ++bindex;
- memcpy( username, buf+1, bindex-1);
- username[bindex-1] = 0;
-
- if (pw = getpwnam(username))
- pw_info.pw_dir = pw->pw_dir;
- else
- pw_info.pw_dir = "~";
- }
-
- strcpy (buf2, pw_info.pw_dir);
- strcat (buf2, buf + bindex);
- strcpy (buf, buf2);
-
- return buf;
- }
- #endif
-
-
- /*-----------------------------options and settings--------------------------*/
- char *Options[] = {
- "method", "ftp",
- "fspsite", "epix.rrze.uni-erlangen.de,21",
- "fspsites", "epix.rrze.uni-erlangen.de,21",
- "mailserv", "ftp.doc.ic.ac.uk",
- "timeout", "30",
- "nomotd", "0",
- "amotd", "0",
- "lmotd", "0",
- "sites", "0",
- "locaminet", "/public/pub/aminet",
- "unpack", "",
- "transfer", "",
- "newest", "0",
- "hide", "",
- "printer", "",
- "dlpath", "",
- "compress", "1",
- "send", "sz",
- "silentdl", "0",
- "readmedl", "0",
- "flatdl", "1",
- "ftpsite", "ftp.eunet.ch",
- "ftpmaster", "ftp.wustl.edu",
- "ftpsites","\
- USA,us.aminet.net,128.252.135.4,,@\
- Germany:Paderborn,de.aminet.net,131.234.22.34,,@\
- UK,uk.aminet.net,193.63.255.4,,@\
- Italy,it.aminet.net,192.132.34.17,,@\
- Sweden,se.aminet.net,130.238.253.4,,@\
- Australia,au.aminet.net,203.16.26.3,,@\
- Germany:Berlin,de2.aminet.net,130.149.17.12,,de.aminet.net@\
- Germany:Erlangen,de3.aminet.net,131.188.3.71,,de.aminet.net@\
- Germany:Trier,de4.aminet.net,136.199.8.81,,de.aminet.net@\
- Germany:Bremen,de5.aminet.net,134.102.228.2,,de.aminet.net@\
- Germany:Stuttgart,de6.aminet.net,129.69.18.15,,de.aminet.net@\
- Germany:Regensburg,de7.aminet.net,132.199.2.11,,de.aminet.net@\
- Germany:K'lautern,de8.aminet.net,131.246.94.94,,de.aminet.net@\
- Germany:Augsburg,de9.aminet.net,141.82.16.242,,de.aminet.net@\
- Germany:Dortmund,de10.aminet.net,129.217.128.54,,de.aminet.net@\
- Germany:Aachen,de11.aminet.net,137.226.225.3,,de.aminet.net@\
- Germany:Clausthal,de12.aminet.net,139.174.253.13,,de.aminet.net@\
- Austria,at.aminet.net,131.130.186.194,,it.aminet.net@\
- France,fr.aminet.net,194.158.96.22,,it.aminet.net@\
- Sweden,se2.aminet.net,130.240.16.39,,se.aminet.net@\
- Croatia,hr.aminet.net,161.53.129.16,,it.aminet.net@\
- Switzerland,ch.aminet.net,146.228.10.11,,it.aminet.net@\
- Denmark,dk.aminet.net,130.225.51.30,,se.aminet.net@\
- Ireland,ie.aminet.net,143.239.1.200,,uk.aminet.net@\
- Spain,es.aminet.net,157.88.36.190,,it.aminet.net@\
- Poland,pl1.aminet.net,194.92.39.69,,uk.aminet.net@\
- Poland,pl2.aminet.net,195.117.124.1,,uk.aminet.net",
- "findmethod", "0",
- "findsite", "",
- "findsites", "\
- USA (MO),us.aminet.net,128.252.135.4,,@\
- Germany,de.aminet.net,131.234.22.34,,@\
- UK,uk.aminet.net,193.63.255.4,,@\
- Italy,it.aminet.net,192.132.34.17,,@\
- Australia,au.aminet.net,203.16.26.3,,",
- 0, 0
- };
-
- #define OBUFLEN 8192
- char obuf[OBUFLEN];
-
- char *option_get(name)
- char *name;
- {
- char **t;
-
- for (t = Options; t[0]; t += 2)
- if (!mystrcmp(name, t[0]))
- return t[1];
-
- return "";
- }
-
- int option_getnum(name)
- char *name;
- {
- return myatoi(option_get(name));
- }
-
- int option_set(name, val)
- char *name, *val;
- {
- char **t;
-
- for (t = Options; t[0]; t += 2)
- if (!mystrcmp(name, t[0]))
- mystrcpy((t[1] = salloc(strlen(val) + 1)), val);
-
- return 0;
- }
-
- int option_setnum(name, val)
- char *name;
- int val;
- {
- char buf[20];
-
- sprintf(buf, "%d", val);
- option_set(name, buf);
-
- return 0;
- }
-
- int option_loadfh(f)
- FILE *f;
- {
- char *t;
-
- fgets(obuf, OBUFLEN, f);
- if (mystrncmp("#adtrc-v2", obuf, 9))
- return 1;
-
- while (myfgets(obuf, OBUFLEN, f)) {
- while (*obuf && obuf[strlen(obuf)-1]=='\\' &&
- myfgets(obuf+strlen(obuf)-1, OBUFLEN-strlen(obuf)-1, f)) ;
-
- for (t = obuf; *t && *t != '='; t++);
-
- if (*t == '=') {
- *t++ = 0;
- option_set(obuf, t);
- }
- }
-
- return 0;
- }
-
- int option_load(name)
- char *name;
- {
- FILE *f;
- int r;
-
- if (!(f = fopen(name, "r")))
- return 1;
-
- r = option_loadfh(f);
-
- fclose(f);
-
- return r;
- }
-
- int option_save(name)
- char *name;
- {
- FILE *f;
- char **t;
-
- if (!(f = fopen(name, "w")))
- return 1;
-
- fprintf(f, "#adtrc-v2\n");
-
- for (t = Options; t[0]; t += 2)
- fprintf(f, "%s=%s\n", t[0], t[1]);
-
- fclose(f);
-
- return 0;
- }
-
- /*-----------------------------input file parser-----------------------------*/
- #define PBUFSIZE 400
- char parsebuf[PBUFSIZE], p_error, *p_ptr;
-
- int reset_token()
- {
- p_ptr = parsebuf;
- p_error = 0;
- return 0;
- }
-
-
- char *get_token()
- {
- char *t, *s, *d;
-
- if (!p_ptr) {
- p_error = 1;
- return "";
- }
- for (t = s = d = p_ptr; *s && *s != '@'; s++) {
- if (*s != '\r')
- *d++ = *s;
- }
-
- if (!*s)
- p_ptr = 0;
- else {
- *s = 0;
- p_ptr = s + 1;
- }
-
- return t;
- }
-
-
- long p_atoi(s)
- char *s;
- {
- long r = 0;
-
- while (*s && *s >= '0' && *s <= '9')
- r = 10 * r + *s++ - '0';
-
- if (*s)
- p_error = 1;
-
- return r;
- }
-
-
- int read_adt_v2(fh)
- FILE *fh;
- {
- ENTRY *e;
- char *t;
-
- do {
- if (*parsebuf == '#')
- if (!mystrncmp(parsebuf, "#endadt", 7))
- break;
- else
- continue;
-
- e = e_alloc();
-
- reset_token();
-
- e->time = p_atoi(get_token());
-
- mystrncpy(e->dir, get_token(), E_DIR);
-
- mystrncpy(e->file, get_token(), E_FILE);
-
- e->size = p_atoi(get_token());
-
- e->readmelen = p_atoi(get_token());
-
- e->readmesize = p_atoi(get_token());
-
- e->version = -1;
-
- e->osversion = -1;
-
- e->status = *get_token()=='R' ? STATUS_REMOTE : STATUS_LOCAL;
-
- mystrncpy(e->desc, get_token(), E_DESC);
-
- for (t = e->desc; *t; t++)
- if (*t == '\n')
- *t = 0;
-
- e->tagged = 0;
-
- if (!(p_error))
- e_add(File, e);
- } while (fgets(parsebuf, PBUFSIZE, fh));
-
- return 0;
- }
-
- /*----------------------------------utility----------------------------------*/
- long newesttime()
- {
- int i;
- long newest = 0;
-
- for (i = 0; i < File->num; i++)
- if ((File->list[i]->time < time(NULL)) && (File->list[i]->time > newest))
- newest = File->list[i]->time;
-
- return newest;
- }
-
- char *temp_name(buf, sub)
- char *buf;
- char *sub;
- {
- sprintf(buf, "%s%s_%s", TEMPPATH, UserName, sub);
- return buf;
- }
-
- struct temp_file {
- FILE *fh;
- char name[100];
- int (*cleanup) ();
- };
- #define TEMPFILE struct temp_file
-
- int temp_delete(tfh)
- TEMPFILE *tfh;
- {
- if (*tfh->name)
- unlink(tfh->name);
- return 0;
- }
-
- int temp_dummy()
- {
- return 0;
- }
-
- char tclose(tfh)
- TEMPFILE *tfh;
- {
- fclose(tfh->fh);
- if (tfh->cleanup)
- (*tfh->cleanup) (tfh);
- return 0;
- }
-
- int exists(name)
- char *name;
- {
- FILE *f;
-
- if ((f = fopen(name, "r")))
- fclose(f);
- return f != 0;
- }
-
- char *tackon(buf, add)
- char *buf, *add;
- {
- if (*buf && (buf[strlen(buf) - 1] != '/' && buf[strlen(buf) - 1] != ':'))
- strcat(buf, "/");
- strcat(buf, add);
-
- return buf;
- }
-
- char *basename(s)
- char *s;
- {
- char *b = s;
-
- for (; *s; s++)
- if (*s == '/' || *s == ':')
- b = s + 1;
-
- return b;
- }
-
-
- #define NUMLINES 500
- char *Lines[NUMLINES + 1];
- char LineBuf[200];
-
- char **read_file(f, title)
- FILE *f;
- char *title;
- {
- int i=0;
- char *t;
-
- if (title) {
- Lines[i]= (char *) salloc( mystrlen(title) + 1 );
- mystrcpy (Lines[i++], title);
- }
-
- for ( ; i < NUMLINES; i++) {
- if (!(fgets(LineBuf, 200, f)))
- break;
- for (t = LineBuf; *t && *t != '\n'; t++);
- *t = 0;
- Lines[i] = (char *) salloc(mystrlen(LineBuf) + 1);
- mystrcpy(Lines[i], LineBuf);
- }
- Lines[i] = 0;
- return Lines;
- }
-
- int free_file(strings)
- char **strings;
- {
- while (*strings)
- free(*strings++);
- return 0;
- }
-
- /*-----------------------------------sorting---------------------------------*/
-
- int cmp_age(e1, e2)
- ENTRY *e1, *e2;
- {
- return e2->time - e1->time;
- }
-
- int cmp_dir(e1, e2)
- ENTRY *e1, *e2;
- {
- int t;
-
- return (t = mystricmp(e1->dir, e2->dir)) ? t : mystricmp(e1->file, e2->file);
- }
-
- int cmp_size(e1, e2)
- ENTRY *e1, *e2;
- {
- return e2->size - e1->size;
- }
-
- int cmp_name(e1, e2)
- ENTRY *e1, *e2;
- {
- return mystricmp(e1->file, e2->file);
- }
-
- int cmp_rage(e2, e1)
- ENTRY *e1, *e2;
- {
- return e2->time - e1->time;
- }
-
- int cmp_rdir(e2, e1)
- ENTRY *e1, *e2;
- {
- int t;
-
- return (t = mystricmp(e1->dir, e2->dir)) ? t : mystricmp(e1->file, e2->file);
- }
-
- int cmp_rsize(e2, e1)
- ENTRY *e1, *e2;
- {
- return e2->size - e1->size;
- }
-
- int cmp_rname(e2, e1)
- ENTRY *e1, *e2;
- {
- return mystricmp(e1->file, e2->file);
- }
-
- struct sort_mode {
- int (*cmp) ();
- char *desc;
- };
- #define SORT struct sort_mode
-
- SORT
- sort_age = { cmp_age, "by age (newest first)" },
- sort_dir = { cmp_dir, "by dir" },
- sort_size = { cmp_size, "by size" },
- sort_name = { cmp_name, "by name" },
- sort_rage = { cmp_rage, "by age (oldest first)" },
- sort_rdir = { cmp_rdir, "reverse by dir" },
- sort_rsize = { cmp_rsize, "reverse by size" },
- sort_rname = { cmp_rname, "reverse by name" };
-
- int quick_sort(av, n, cmp)
- ENTRY **av;
- int n, (*cmp) ();
- {
- ENTRY **i, **j, *x, *t;
-
- if (n > 0) {
- i = av;
- j = av + n - 1;
- x = av[n >> 1];
- do {
- while (cmp(*i, x) < 0)
- i++;
- while (cmp(x, *j) < 0)
- --j;
- if (i <= j)
- t = *i, *i = *j, *j = t, i++, j--;
-
- } while (i <= j);
-
- if (j + 1 - av < av + n - i) {
- quick_sort(av, j + 1 - av, cmp);
- quick_sort(i, av + n - i, cmp);
- } else {
- quick_sort(i, av + n - i, cmp);
- quick_sort(av, j + 1 - av, cmp);
- }
- }
- return 0;
- }
-
- int sort_list(list, sort)
- LIST *list;
- SORT *sort;
- {
-
- quick_sort(list->list, list->num, sort->cmp);
-
- list->current = list->offset = 0;
-
- Vis->sort = sort->desc;
-
- return 0;
- }
-
-
- /*---------------------------------visibility--------------------------------*/
-
- int allvisible()
- {
- int i;
-
- l_store();
- l_reset(Vis);
-
- Vis->sel = "All files";
- for (i = 0; i < File->num; i++)
- e_add(Vis, File->list[i]);
-
- sort_list(Vis, &sort_dir);
-
- return 0;
- }
-
- int invisible()
- {
- ENTRY **entr = Vis->list;
- char buf[200], *b, *h = option_get("hide");
- int i, j;
-
- while (*h) {
- b = buf;
- while (*h && *h != ' ' && *h != ',')
- *b++ = *h++;
- *b = 0;
-
- while (*h && (*h == ' ' || *h == ','))
- h++;
-
- if (!*buf)
- continue;
-
- for (i = j = 0; i < Vis->num; i++)
- if (mystrncmp(buf, entr[i]->dir, b - buf))
- entr[j++] = entr[i];
- Vis->num = j;
- }
- Vis->current = 0;
-
- return 0;
- }
-
- int newvisible()
- {
- ENTRY **entr = File->list;
- int i;
-
- l_store();
- l_reset(Vis);
- Vis->sel = "New files";
-
- for (i = 0; i < File->num; i++)
- if (entr[i]->time > LastCall)
- e_add(Vis, entr[i]);
-
- invisible();
-
- if (!Vis->num && File->num)
- NoFilesString = "No new files since your last call, use v)iew k)nown to see older ones";
-
- sort_list(Vis, &sort_dir);
-
- return 0;
- }
-
- int dirvisible(dir)
- char *dir;
- {
- ENTRY **entr = File->list;
- int i, l = strlen(dir);
-
- l_store();
- l_reset(Vis);
- Vis->sel = "Selected dir";
-
- for (i = 0; i < File->num; i++)
- if (!mystrncmp(entr[i]->dir, dir, l))
- e_add(Vis, entr[i]);
-
- if (!Vis->num && File->num)
- NoFilesString = "No files matching that directory specification";
-
- sort_list(Vis, &sort_dir);
-
- return 0;
- }
-
- int findstr(str)
- char *str;
- {
- ENTRY **entr = File->list;
- int i;
-
- if (!*str)
- return 0;
-
- l_store();
- l_reset(Vis);
-
- for (i = 0; i < File->num; i++)
- if (mystristr(str, entr[i]->desc) || mystristr(str, entr[i]->file))
- e_add(Vis, entr[i]);
-
- Vis->sel = "Matching files";
-
- sort_list(Vis, &sort_dir);
-
- if (!Vis->num && File->num)
- NoFilesString = "No files matching substring, use f)ind to search again";
-
- return 0;
- }
-
-
- int strlimit(str)
- char *str;
- {
- ENTRY **entr = Vis->list;
- int i, j;
-
- if (!*str)
- return 0;
-
- l_store();
- Vis->sel = "Matching files";
-
- for (i = j = 0; i < Vis->num; i++)
- if (mystristr(str, entr[i]->desc) || mystristr(str, entr[i]->file))
- entr[j++] = entr[i];
-
- Vis->num = j;
- Vis->current = 0;
-
- if (!Vis->num && File->num)
- NoFilesString = "No files matching substring, use v)iew to see more";
-
- return 0;
- }
-
- int togglevisible()
- {
- LIST *l;
-
- l = Vis;
- Vis = Alt;
- Alt = l;
- return 0;
- }
-
-
- int markedvisible()
- {
- ENTRY **entr;
- int i, j=0;
-
- l_store();
- Vis->sel = "Marked files";
-
- entr = Vis->list;
- for (i = 0; i < Vis->num; i++)
- if (entr[i]->tagged)
- entr[j++]=entr[i];
-
- if (!(Vis->num=j) && File->num)
- NoFilesString = "No tagged files";
-
- return 0;
- }
-
- int markedextract()
- {
- ENTRY **entr = Vis->list;
- int i;
-
- l_reset(Mark);
-
- for (i = 0; i < Vis->num; i++)
- if (entr[i]->tagged)
- e_add(Mark, entr[i]);
-
- if (!Mark->num)
- e_add(Mark, entr[Vis->current]);
-
- return 0;
- }
-
-
-
- /*-----------------------------string formatting-----------------------------*/
- char *ShowFiles = "New files by dir";
- int CurSelected, Window;
-
- char *str_topline(buf, len, list)
- LIST *list;
- int len;
- char *buf;
- {
- int i;
- char buf2[40];
-
- for (i = 0; i < len; i++)
- buf[i] = ' ';
- buf[i] = 0;
-
- sprintf(buf2, "Showing: %d/%d", list->num, File->num);
- strcpy(buf, buf2);
- buf[strlen(buf)] = ' ';
-
- sprintf(buf2, "%s %s", Vis->sel, Vis->sort);
- strcpy(buf + len / 2 - strlen(buf2) / 2, buf2);
- buf[strlen(buf)] = ' ';
-
- sprintf(buf2, "Page: %d/%d", 1 + list->offset / Window, 1 + list->num / Window);
- strcpy(buf + len - strlen(buf2), buf2);
-
- return buf;
- }
-
-
- char sizestr[10];
-
- char *str_ksize(size)
- long size;
- {
- if (size == -1) {
- sprintf(sizestr, "?");
- } else {
- size = (size + 512) / 1024;
- if (size <= 999)
- sprintf(sizestr, "%dK", size);
- else if ((size + 512) / 1024 < 10)
- sprintf(sizestr, "%d.%dM", size / 1024, (size * 10 + 512) / 1024 % 10);
- else
- sprintf(sizestr, "%dM", (size + 512) / 1024);
- }
- return sizestr;
- }
-
-
- char *str_titles(buf)
- char *buf;
- {
- switch (Dispmode) {
- case 0:
- strcpy(buf, " File Dir Size Description\n");
- break;
- }
- return buf;
- }
-
-
-
- char *str_entry(e, n, max, buf, len)
- ENTRY **e;
- int n, max, len;
- char *buf;
- {
- int i;
-
- if (n >= max) {
- for (i = 0; i < len; i++)
- buf[i] = ' ';
- buf[i] = 0;
- return buf;
- }
- switch (Dispmode) {
- case 0:
- sprintf(buf, "%c%-20.20s %-10.10s %4.4s%c%-80.80s",
- e[n]->tagged ? '+' : ' ',
- e[n]->file,
- e[n]->dir,
- str_ksize(e[n]->size),
- e[n]->readmesize > 100 ? '+' : ' ',
- e[n]->desc);
- buf[len - 1] = 0;
- break;
- }
-
-
- return buf;
- }
-
-
- char sitebuf[120];
-
- int str_sitesplit(s, parts)
- char *s, **parts;
- {
- char *d = sitebuf;
- int i;
-
- for (i = 0; i < 5; i++) {
- parts[i] = d;
- while (*s && *s != ',' && *s != '@')
- *d++ = *s++;
- if (*s == ',')
- s++;
- *d++ = 0;
- }
-
- return 0;
- }
-
- char *str_showline(entries, n, max, buf)
- char *entries, *buf;
- int n, max;
- {
- char *s = entries;
- char *parts[10];
-
- if (n >= max)
- return "";
-
- for (; n > 0; n--)
- while (*s++ != '@');
-
- str_sitesplit(s, parts);
- sprintf(buf, "%-12.12s %24.24s", parts[0], parts[1]);
-
- return buf;
- }
-
- char centerbuf[250];
-
- char *str_center(s, len)
- char *s;
- int len;
- {
- int i = (len - strlen(s)) / 2 - 1;
-
- strcpy(centerbuf + i, s);
- while (i > 0)
- centerbuf[--i] = ' ';
-
- return centerbuf;
- }
-
-
- int str_longest(arr)
- char **arr;
- {
- int l = 0;
-
- for (; *arr; arr++)
- if (strlen(*arr) > l)
- l = strlen(*arr);
- return l;
- }
-
- int str_shift(len, width)
- int len, width;
- {
- return len < width ? (width - len) / 2 : 0;
- }
-
- LIST sitelist = {0, str_showline, 0, 0, 0, 0, 1, 0};
-
- int setup_sitelist(sitesname, sitename, help)
- char *sitesname, *sitename, **help;
- {
- int t, n = 1;
- char *sites = option_get(sitesname), *s;
- char buf[100], *d = buf;
-
- mystrcpy(buf, option_get("ftpsite"));
-
- for (s = sites; *s; ) {
- if (*s++ == '@') {
- if (*buf && !mystrncmp(s, buf, strlen(buf)))
- sitelist.current = n;
- n++;
- }
- }
-
- sitelist.list = (ENTRY **) sites;
- sitelist.num = n;
-
- if ((t = disp_choice(help, &sitelist)) < 0)
- return 1;
-
- for (s = sites; t > 0; t--)
- while (*s++ != '@');
-
- while (*s && *s != '@')
- *d++ = *s++;
- *d++ = 0;
-
- option_set(sitename, buf);
-
- return 0;
- }
-
- /*-----------------------------command key input-----------------------------*/
- #define K_UP 300
- #define K_DOWN 301
- #define K_RIGHT 302
- #define K_LEFT 303
-
- int inp_getchr()
- {
- int c;
-
- if ((c = disp_getchar()) != 27 && c != 155)
- return c;
-
- if (c == 27 && (c = disp_getchar()) != '[')
- return c;
-
- switch (c = disp_getchar()) {
- case 'A':
- return K_UP;
- case 'B':
- return K_DOWN;
- case 'C':
- return K_RIGHT;
- case 'D':
- return K_LEFT;
- }
- return 0;
- }
-
- /*-------------------------------initial setup-------------------------------*/
- char *setup_showline(entries, n, max)
- TRANSFER entries[];
- int n, max;
- {
- return n < max ? entries[n].text : "";
- }
-
- LIST setuplist = {(ENTRY **) TransferTypes, setup_showline, 0, 0, 0, 0, 1, 0};
-
- char *FirstSetupHelp[] = {
- "ADT initial setup",
- "It seems that you've never used ADT before. ADT lets you access files",
- "stored in an Aminet database using various methods (FTP, FSP, mail",
- "servers and local files). The version you have here may not support all",
- "of those though. Select your transfer method now.",
- "NOTE: After setup, you can press 'h' or '?' in most places to get help.",0
- };
-
- char *SetupHelp[] = {
- "ADT transfer method setup",
- "Please select the way ADT should use to access files on Aminet", 0
- };
-
- int setup_method()
- {
- TRANSFER *type;
- int n;
-
- setuplist.current = 0;
- setuplist.num = 0;
- for (type = TransferTypes; type->text; type++) {
- if (!mystrcmp(type->name, option_get("method")))
- setuplist.current = setuplist.num;
- setuplist.num++;
- }
-
- n = disp_choice(InitialSetup ? FirstSetupHelp : SetupHelp, &setuplist);
-
- if (n < 0) {
- if (InitialSetup)
- exit_adt("Cannot start up without a transfer method. Goodbye.");
- } else {
- if (trans_close)
- trans_close();
- option_set("method", TransferTypes[n].name);
- TransferTypes[n].init();
- trans_options();
- }
-
- return 0;
- }
-
-
- char *DefaultsHelp[] = {
- "ADT initial setup",
- "It seems that you've never used ADT before. ADT lets you access files",
- "stored in ADT databases using various methods (FTP, FSP, mailservers,",
- "local files. Your sysadmin has selected a default transfer method and",
- "default site for you. They will be saved as your local configuration",
- "when you q)uit ADT. You may change them anytime using the o)ptions",
- "command.",
- "Press any key to enter ADT", 0
- };
-
- int setup_defaults()
- {
- option_set("newest", "0");
-
- return 0;
- }
-
-
-
- char *enum_showline(entries, n, max, buf)
- char **entries, *buf;
- int n, max;
- {
- if (n >= max)
- return "";
- else
- return entries[n];
- }
-
-
- LIST enumlist = {0, enum_showline, 0, 0, 0, 0, 1, 0};
-
- int setup_enumed(help, choices, var)
- char **help, **choices, *var;
- {
- int n, lines, t;
-
- for (lines = 0; choices[lines]; lines++);
-
- n = option_getnum(var);
- if (n < 0)
- n = 0;
- if (n >= lines)
- n = lines - 1;
-
- enumlist.list = (ENTRY **) choices;
- enumlist.num = lines;
- enumlist.current = n;
-
- t = disp_choice(help, &enumlist);
-
- if (t >= 0)
- option_setnum(var, t);
-
- return t;
- }
-
-
- char *FindMethodHelp[] = {
- "Find method",
- "Please choose the method to use for finding files on Aminet. You can use",
- "an archie-like find server if you have Internet access. If you don't,",
- "or if you want to make several queries at once, or if your connection to",
- "Aminet is very fast (e.g. local files), it may be advisable for ADT to",
- "download the complete file list and do the queries locally. If you only",
- "want to search what's available at your site, pick the third option.", 0
- }, *FindMethodList[] = {
- "Remote server search of complete Aminet index",
- "Local search of current Aminet site",
- "Local search of complete Aminet index", 0
- };
-
- char *FindSiteHelp[] = {
- "Find site selection",
- "Which server should be used for finding stuff? All servers have a complete",
- "Aminet index and can thus be used for searches on any of the complete sites", 0
- };
-
- int setup_findmethod()
- {
- if (setup_enumed(FindMethodHelp, FindMethodList, "findmethod") == 0)
- setup_sitelist("findsites", "findsite", FindSiteHelp);
-
- option_save(ConfigFile);
-
- return 0;
- }
-
- /* ==============================GENERIC FILE TRANSFER======================== */
- int trans_init()
- {
- TRANSFER *t = TransferTypes;
- char *s = option_get("method");
-
- while (t->name && mystrcmp(t->name, s))
- t++;
-
- if (!t->name)
- return 1;
-
- t->init();
-
- return 0;
- }
-
-
- /* ==============================LOCAL FILE PACKAGE=========================== */
- int CdRom;
-
- int local_connect(progress)
- int (*progress) ();
- {
- Connected = 1;
- return 0;
- }
-
- int local_remopen(tfh, remote)
- TEMPFILE *tfh;
- char *remote;
- {
- strcpy(tfh->name, option_get("locaminet"));
- tackon(tfh->name, remote);
-
- tfh->cleanup = temp_dummy;
- tfh->fh = fopen(tfh->name, "r");
-
- NoFilesString = "Could not access remote file, use o)ptions s)ite to change path";
-
- return 0;
- }
-
- int local_download(remote, locdir, size, progress)
- char *remote, *locdir;
- long size;
- int (*progress) ();
- {
- char buf[150], buf2[100];
-
- sprintf(buf, "Copying %s", remote);
- progress(buf);
-
- strcpy(buf2, option_get("locaminet"));
- tackon(buf2, remote);
-
- sprintf(buf, "%s %s %s", COPYCMD, buf2, locdir);
- system(buf);
-
- sprintf(buf, "Copied %s", remote);
- progress(buf);
-
- return 0;
- }
-
- int local_disconnect()
- {
- Connected = 0;
- return 0;
- }
-
- #ifdef AMIGA
- char *LocAminetHelp[] = {
- "Use a local Aminet database",
- "Please enter the absolute path to the Aminet files up to the aminet/",
- "directory, e.g. NET:aminet", 0
- };
-
- char *CdRomHelp[] = {
- "Use an Aminet CDROM",
- "Please enter the absolute path to your Aminet CDROM (or any other non",
- "updated Aminet file collection), including the Aminet/ end of the path,",
- "e.g. CD0:Aminet . Note that you need at least Aminet CD 2.", 0
- };
-
- #else
-
- char *LocAminetHelp[] = {
- "Use a local Aminet database",
- "Please enter the absolute path to the Aminet files. You must not use the",
- "tilde ~ sign. Enter the path up to the aminet dir, eg. /ftp/pub/aminet .", 0
- };
-
- char *CdRomHelp[] = {
- "Please enter the absolute path to your Aminet CDROM (or any other non",
- "updated Aminet file collection), including the Aminet/ end of the path,",
- "e.g. CD0:Aminet . Note that you need at least Aminet CD 2.", 0
- };
- #endif
-
-
-
-
- int local_options()
- {
- char buf[100];
-
- if (InitialSetup)
- option_set("findmethod", "1");
-
-
- mystrcpy(buf, option_get("locaminet"));
- disp_inputstr(buf, CdRom ? CdRomHelp : LocAminetHelp);
- option_set("locaminet", buf);
-
- return 0;
- }
-
- int local_close()
- {
- return 0;
- }
-
-
- int local_init()
- {
- trans_options = local_options;
- trans_connect = local_connect;
- trans_remopen = local_remopen;
- trans_download = local_download;
- trans_disconnect = local_disconnect;
- trans_close = local_close;
-
- if ( !strcmp ( option_get("method"), "cdrom"))
- CdRom=1;
-
- return 0;
- }
-
- /* ==============================EXTERNAL FTP PACKAGE========================= */
- #ifndef NO_EXTERNAL_FTP
-
- FILE *xFtp;
-
- int xftp_connect(progress)
- int (*progress) ();
- {
- char *site = option_get("ftpsite");
- char *parts[10],passwd[32];
- char buf[100];
-
- if (Connected)
- return 0;
- Connected = 1;
-
- str_sitesplit(site, parts);
-
- sprintf(buf, "Connecting to %s", parts[1]);
- progress(buf);
-
- sprintf(passwd,"user ftp %s@\n",getlogin());
-
- fprintf(xFtp, "open %s\n", parts[1]);
- fprintf(xFtp, passwd);
- fprintf(xFtp, "cd pub/aminet\n");
- fprintf(xFtp, "bin\n");
-
- return 0;
- }
-
- #ifdef AMIGA
- #define xftp_filesize(name) 0
- #else
-
- static long xftp_filesize(name)
- char *name;
- {
- struct stat st;
-
- return stat(name, &st) ? -1 : st.st_size;
- }
- #endif
-
- static int xftp_waitfile(local, size, progress, maxwait, pad, name)
- char *local;
- long size;
- int (*progress) (), maxwait;
- char *pad, *name;
- {
- int got, prevgot = -1, timeout = 0;
- char buf[100];
-
- sprintf(buf, "Initiating download of %s", size < 0 ? name : local);
- progress(buf);
-
- while ((got = xftp_filesize(local)) < size || size < 0) {
-
- if (got != prevgot)
- timeout = 0;
-
- if (timeout > maxwait)
- return 1;
-
- if (++timeout > 10) {
- sprintf(buf, "Timeout %d on file %s", maxwait - timeout, local);
- progress(buf);
- }
- prevgot = got;
- if (got >= 0) {
- if (size >= 0)
- sprintf(buf, "Downloading %s, %3dK/%3dK",
- local, (got + 512) / 1024, (size + 512) / 1024);
- else
- sprintf(buf, "Downloading %s, %3dK", name, (got + 512) / 1024);
-
- progress(buf);
- }
- if (size < 0 && exists(pad))
- return 0;
-
- sleep(1);
- }
-
- return size >= 0 ? got < size : 0;
- }
-
- int xftp_remopen(tfh, remote, pack, progress)
- TEMPFILE *tfh;
- char *remote, *pack;
- int (*progress) ();
- {
- char pad[100], buf[100], remname[100];
-
- sprintf(remname, "%s%s", remote, pack);
-
- temp_name(pad, "PAD");
- temp_name(tfh->name, "REMOTE");
- strcat(tfh->name, pack);
- tfh->cleanup = temp_delete;
-
- unlink(pad);
- unlink(tfh->name);
-
- fprintf(xFtp, "get %s %s\n", remname, tfh->name);
- fprintf(xFtp, "get info/adt/pad %s\n", pad);
- fflush(xFtp);
-
- xftp_waitfile(tfh->name, -1, progress, 30, pad, basename(remname));
-
- unlink(pad);
-
- if (*pack) {
- temp_name(tfh->name, "REMOTE");
- unlink(tfh->name);
- sprintf(buf, "%s %s", pack[2] ? "gzip -d" : "uncompress", tfh->name);
- system(buf);
- }
- tfh->fh = fopen(tfh->name, "r");
-
- return 0;
- }
-
-
- int xftp_download(remote, locdir, size, progress)
- char *remote, *locdir;
- int size, (*progress) ();
- {
- char locname[200];
-
- strcpy(locname, locdir);
- tackon(locname, basename(remote));
-
- fprintf(xFtp, "get %s %s\n", remote, locname);
- fflush(xFtp);
-
- xftp_waitfile(locname, size, progress, 30, 0);
-
- return 0;
- }
-
-
- int xftp_disconnect()
- {
- if (!Connected)
- return 0;
- Connected = 0;
-
- fprintf(xFtp, "close\n");
- fflush(xFtp);
- return 0;
- }
-
- char *XFTPHelp[] = {
- "External FTP client setup",
- "You need a site where you retrieve your files from. Pick one that is",
- "close to where you live, and later experiment around to find out which",
- "one's the best for you.", 0
- };
-
-
- int xftp_options()
- {
- setup_sitelist("ftpsites", "ftpsite", XFTPHelp);
-
- return 0;
- }
-
- int xftp_close()
- {
- if (xFtp) {
- fprintf(xFtp, "bye\n");
- pclose(xFtp);
- xFtp = 0;
- Connected = 0;
- }
- return 0;
- }
-
- int xftp_init()
- {
- char buf[100];
-
- sprintf(buf, "ftp -n");
-
- if (!xFtp && !(xFtp = popen(buf, "w")))
- exit_adt("Could not start 'ftp'");
-
- trans_options = xftp_options;
- trans_connect = xftp_connect;
- trans_remopen = xftp_remopen;
- trans_download = xftp_download;
- trans_disconnect = xftp_disconnect;
- trans_close = xftp_close;
-
- return 0;
- }
-
- #endif
-
-
- /* ==============================TCP functions========================= */
- #ifndef NO_TCP_UTILITY
-
- /* creates an new tcp socket and connects it to <host> on port <port>. returns
- * -1 if a failure occured. NOTE: host can either be a hostname or a
- * dot-notation of the internet adress */
- int tcp_createsocket(host, port)
- char *host;
- int port;
- {
- struct sockaddr_in sin;
- struct hostent *h;
- int connected, net = -1;
-
- if ((sin.sin_addr.s_addr = inet_addr(host)) == -1) {
- if (!(h = gethostbyname(host)))
- return -1;
- else {
- sin.sin_family = h->h_addrtype;
-
- #ifndef NOT43
- memcpy((caddr_t) & sin.sin_addr, h->h_addr_list[0], h->h_length);
- #else
- memcpy((caddr_t) & sin.sin_addr, h->h_addr, h->h_length);
- #endif
- }
- } else
- sin.sin_family = AF_INET;
-
- sin.sin_port = htons(port);
-
- for (connected = 1; connected && (connected < 30); connected++) {
- if ((net = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return -1;
-
- if (connect(net, (struct sockaddr *) & sin, sizeof(sin)) >= 0) {
- connected = 0;
- break;
- } else
- close(net);
- }
-
- if (!connected)
- return net;
- else
- return -1;
- }
-
- #endif
-
- /* ==============================BUILTIN FTP PACKAGE========================= */
- #ifndef NO_BUILTIN_FTP
-
- #ifndef BFTP_BUFSIZE
- # define BFTP_BUFSIZE 10000
- #endif
-
- FILE *bftp_io = NULL;
-
- char *BFTPHelp[] =
- {
- "Builtin FTP client setup",
- "You'll need a site where you retrieve your files from. Pick one that is",
- "close to where you live, and later experiment around to find out which",
- "one's the best for you.", 0
- };
-
- int bftp_options()
- {
- return setup_sitelist("ftpsites", "ftpsite", BFTPHelp);
- }
-
- int bftp_disconnect()
- {
- Connected = 0;
-
- if (bftp_io)
- fclose(bftp_io);
- bftp_io = NULL;
-
- return 0;
- }
-
- int bftp_close()
- {
- return bftp_disconnect();
- }
-
- /* Send FTP command and wait for reply. Returns 0 on failure. */
- int bftp_cmd(cmd)
- char *cmd;
- {
- char buf[256];
- int result;
-
- if (!bftp_io)
- return 0;
-
- if (cmd) {
- fflush(bftp_io);
- rewind(bftp_io);
- fputs(cmd, bftp_io);
- }
- fflush(bftp_io);
- rewind(bftp_io);
- if (!fgets(buf, sizeof(buf), bftp_io))
- return 0;
-
- result = myatoi(buf);
-
- while ((buf[3] != ' ') || (myatoi(buf) != result)) {
- if (!fgets(buf, sizeof(buf), bftp_io))
- return 0;
- }
-
- return (result >= 100) && (result < 400);
- }
-
- int bftp_getdataconnection()
- {
- struct sockaddr_in sin;
- struct hostent *hp;
- int d, i;
- unsigned char *a, *p;
- char buf[80];
-
- i = sizeof(sin);
- if (getsockname (fileno(bftp_io), (struct sockaddr *)&sin, &i))
- return -1;
-
- /* clear Port, let system choose */
- sin.sin_port = 0;
-
- if ((d = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
- return -1;
-
- i = sizeof(sin);
- if ((bind(d, (struct sockaddr *) & sin, i) < 0) ||
- (getsockname(d, (struct sockaddr *) & sin, &i) < 0) ||
- (listen(d, 1) < 0)) {
- close(d);
- return -1;
- }
- a = (unsigned char *) &sin.sin_addr;
- p = (unsigned char *) &sin.sin_port;
-
- sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\n", a[0], a[1], a[2], a[3], p[0], p[1]);
- if (!bftp_cmd(buf)) {
- close(d);
- return -1;
- }
- return d;
- }
-
- int bftp_getfile(remote, local, size, progress)
- char *remote, *local;
- int size, (*progress) ();
- {
- FILE *out = NULL;
- int s = -1, d = -1, i, got = 0, result = 0;
- char *buf, *msg = NULL, tmp[80];
- struct sockaddr_in sin;
-
- if (!Connected)
- return 0;
-
- buf = salloc(BFTP_BUFSIZE);
-
- sprintf(buf, "Getting %s...", remote);
- progress(buf);
-
- if ((s = bftp_getdataconnection()) >= 0) {
- sprintf(buf, "RETR %s\n", remote);
- if (bftp_cmd(buf)) {
- i = sizeof(sin);
- if ((d = accept(s, (struct sockaddr *) & sin, &i)) >= 0) {
- if ((out = fopen(local, "w"))) {
- int len, k, start = time(NULL), t;
- float kps;
-
- while ((len = read(d, buf, BFTP_BUFSIZE)) > 0) {
- if (fwrite(buf, len, 1, out) != 1) {
- close(s);
- fclose(out);
- msg = "Error writing to local file";
- break;
- }
- got += len;
-
- if (progress) {
- k = (got + 512) / 1024;
- kps = (float)got / (float)((t = time(NULL) - start) ? t * 1024 : 1024);
- kps = (int)(kps*10.0) / 10.0;
-
- if (size > 0)
- sprintf(tmp, "Downloading %s, %4dK/%4dK (%#3.3g Kbyte/s)",
- remote, k, (size + 512) / 1024, kps);
- else
- sprintf(tmp, "Downloading %s, %4dK (%#3.3g Kbyte/s)", remote, k, kps);
-
- progress(tmp);
- }
- }
-
- close(d);
- d = -1;
-
- if (bftp_cmd(NULL) && ((size <= 0) || (got == size)))
- result = 1;
- else {
- sprintf(buf, "Error getting file %s (got %d bytes instead of %d)",
- remote, got, size);
- msg = buf;
- }
- } else
- msg = "Cannot create local file";
- } else
- msg = "Cannot establish data connection to ftp site";
- } else
- msg = "Cannot get file from ftp site";
- } else
- msg = "Cannot initiate data connection to ftp site";
-
- if (progress && msg) {
- sleep(1);
- progress(msg);
- sleep(2);
- }
-
- if (d >= 0)
- close(d);
- if (s >= 0)
- close(s);
- if (out)
- fclose(out);
- free(buf);
-
- return result;
- }
-
- int bftp_connect(progress, remote)
- int (*progress) ();
- int remote;
- {
- char *parts[10], buf[100], passwd[32] , *msg = NULL;
- struct servent *sp;
- int s, port = 21;
- char *site;
-
- if (Connected)
- return 1;
- Connected = 1;
-
- str_sitesplit(option_get("ftpsite"), parts);
-
- if (remote)
- sprintf(buf, "Connecting to %s (master site)", site=parts[*parts[4]? 4:1]);
- else
- sprintf(buf, "Connecting to %s", site=parts[1]);
-
- progress(buf);
-
- if ((sp = getservbyname("ftp", "tcp")))
- port = ntohs(sp->s_port);
-
- sprintf(passwd,"PASS %s@\n",getlogin()); /* take users login name as passwd */
-
- if ((s = tcp_createsocket(site, port)) >= 0) {
- if ((bftp_io = fdopen(s, "r+"))) {
- sprintf (buf, "CWD %s\n", *parts[3] ? parts[3] : "pub/aminet");
- if (bftp_cmd(NULL) &&
- bftp_cmd("USER ftp\n") &&
- bftp_cmd(passwd) &&
- bftp_cmd( buf ) &&
- bftp_cmd("TYPE I\n"))
- return 0;
- else
- msg = "Login failed, probably user limit reached, retry later.";
- } else {
- close(s);
- msg = "Could not communicate with ftp site.";
- }
- } else
- msg = "Could not connect to ftp site.";
-
- bftp_close();
-
- if (msg) {
- sleep(1);
- progress(msg);
- sleep(2);
- }
-
- return 1;
- }
-
- int bftp_remopen(tfh, remote, pack, progress)
- TEMPFILE *tfh;
- char *remote, *pack;
- int (*progress) ();
- {
- char buf[200];
-
- tfh->fh = NULL;
- temp_name(tfh->name, "RECENT");
- strcat(tfh->name, pack);
- tfh->cleanup = temp_delete;
-
- unlink(tfh->name);
-
- sprintf(buf, "%s%s", remote, pack);
-
- if (bftp_getfile(buf, tfh->name, 0, progress)) {
- if (*pack) {
- temp_name(tfh->name, "RECENT");
- unlink(tfh->name);
-
- progress ("Uncompressing");
- if (pack[2]) {
- sprintf(buf,"gzip -d <%s%s >%s", tfh->name, pack, tfh->name);
- } else {
- sprintf(buf,"uncompress <%s%s >%s", tfh->name, pack, tfh->name);
- }
- system(buf);
- sprintf(buf,"%s%s",tfh->name,pack);
- unlink (buf);
- }
-
- tfh->fh = fopen(tfh->name, "r");
- }
- NoFilesString = "Could not download index file";
-
- return 0;
- }
-
- int bftp_download(remote, locdir, size, progress)
- char *remote, *locdir;
- int size, (*progress) ();
- {
- char buf[200];
-
- strcpy(buf, locdir);
- tackon(buf, basename(remote));
-
- bftp_getfile(remote, buf, size, progress);
-
- return 0;
- }
-
- int bftp_init()
- {
- Connected = 0;
- trans_options = bftp_options;
- trans_connect = bftp_connect;
- trans_disconnect = bftp_disconnect;
- trans_remopen = bftp_remopen;
- trans_download = bftp_download;
- trans_close = bftp_close;
-
- return 0;
- }
-
- #endif
-
- /* =================================FIND CLIENT=============================== */
- #ifndef NO_FIND_CLIENT
-
- #define FINDD_PORT 1848
-
- FILE *findd_fgrep(host, string, max)
- char *host, *string;
- int max;
- {
- int fd;
- char buf[200];
- int port= FINDD_PORT;
-
- sprintf(buf, "Connecting to findserver %s...", host);
- disp_clear();
- disp_report(buf);
-
- if ((fd = tcp_createsocket(host, port)) >= 0) {
- sprintf(buf, "max %d ; ADTfind %s ; quit\r\n", max, string);
- write(fd, buf, strlen(buf));
- return fdopen(fd, "r");
- } else {
- sleep(1);
- disp_report("Could not connect to find server");
- sleep(2);
- }
-
- return NULL;
- }
-
-
- #else
-
- char *NoFinddHelp[] =
- {
- "Sorry, no find daemon compiled into this version", 0
- };
-
- FILE *findd_fgrep(host, port, string, max)
- char *host, *string;
- int port, max;
- {
- disp_confirm(NoFinddHelp, 0);
- return NULL;
- }
-
- #endif
-
- /* =================================MAIN PROGRAM============================== */
-
- int adt_connect (progress, remote)
- int (*progress) ();
- int remote;
- {
- return trans_connect (progress, remote);
- }
-
- int adt_disconnect ()
- {
- trans_disconnect ();
- return 0;
- }
-
- #ifdef SIGINT
- void adt_breakcheck (sig)
- int sig;
- {
- signal(SIGINT, adt_breakcheck);
-
- if (!MaskSIGINT || (MaskSIGINT && GotSIGINT))
- exit_adt ("Aborted");
- GotSIGINT=1;
- }
- #endif
-
-
- int tagcurrent()
- {
- if (Vis->num && Vis->list[Vis->current])
- Vis->list[Vis->current]->tagged ^= 1;
-
- return 0;
- }
-
- int tagall()
- {
- int tag, i;
- ENTRY **e = Vis->list;
-
- if (Vis->num) {
- tag = Vis->list[0]->tagged ^ 1;
- for (i = 0; i < Vis->num; i++)
- e[i]->tagged = tag;
- }
- return 0;
- }
-
- char transferdesc[200];
-
- char *transferstr()
- {
- char *proc = Action ? (Action == 2 ? "unpack" : "send") : "none";
-
- sprintf(transferdesc,
- "Action: %-6s Path: %-16.16s Readmes: %c Subdirs: %c Verbose: %c",
- proc, Path, Readme ? 'y' : 'n', Flat ? 'n' : 'y', Silent ? 'n' : 'y');
-
- return transferdesc;
- }
-
- int progress_dummy()
- {
- return 0;
- }
-
- int make_dirs(path)
- char *path;
- {
- char buf[200], *s = path, *d = buf;
-
- do {
- while (*s && *s != '/')
- *d++ = *s++;
-
- *d = 0;
-
- if (access(buf, 3))
- makedir(buf, 0755);
-
- if (*s)
- *d++ = *s++;
- } while (*s);
-
- return 0;
- }
-
-
- int do_action(locdir, remname)
- char *locdir, *remname;
- {
- char locname[200];
- char buf[200];
- int len;
-
- strcpy(locname, locdir);
- tackon(locname, basename(remname));
-
- if (Action == 1) {
- sprintf(buf, "%s %s", option_get("send"), locname);
- system(buf);
- sleep(2);
- disp_refresh();
- }
- if (Action == 2) {
- len = mystrlen(locname);
-
- if (len > 4 && !mystricmp(locname + len - 4, ".lha")) {
- puts("");
- sprintf(buf, "cd %s;lha e %s", locdir, locname);
- system(buf);
- disp_refresh();
- } else if (len > 2 && !mystrcmp(locname + len - 2, ".Z")) {
- puts("");
- sprintf(buf, "cd %s;uncompress %s", locdir, locname);
- system(buf);
- disp_refresh();
- } else if (len > 3 && !mystrcmp(locname + len - 3, ".gz")) {
- puts("");
- sprintf(buf, "cd %s;gzip -d %s", locdir, locname);
- system(buf);
- disp_refresh();
- }
- }
- return 0;
- }
-
- int get_files(progress, showfile)
- int (*progress) (), (*showfile) ();
- {
- ENTRY *e;
- char locdir[200], remname[200];
- int i, p, err = 0, n;
-
- if (Silent)
- progress = progress_dummy;
-
-
- MaskSIGINT = 1;
-
- for (p=0; p<2; p++) {
-
- for (i = n = 0; i < Vis->num; i++)
- if ( (Vis->list[i]->status & 1) == p)
- n++;
-
- if (!n)
- continue;
-
- if (adt_connect(progress, p))
- continue;
-
- for (i = 0; i < Vis->num; i++) {
- e = Vis->list[i];
-
- if ((e->status & 1) != p)
- continue;
-
- showfile (Vis, i);
-
- mystrcpy(locdir, option_get("dlpath"));
- glob_path(locdir);
- if (!Flat)
- tackon(locdir, e->dir);
- make_dirs(locdir);
-
- strcpy(remname, e->dir);
- tackon(remname, e->file);
-
- if (!*locdir)
- strcpy(locdir, CURDIR);
-
- if ((err = trans_download(remname, locdir, e->size, progress)))
- break;
-
- if ( GotSIGINT )
- break;
-
- do_action(locdir, remname);
-
- if (Readme) {
- strcpy(remname, e->dir);
- tackon(remname, get_readme(e));
-
- if ((err = trans_download(remname, locdir, e->readmesize, progress)))
- break;
-
- if ( GotSIGINT )
- break;
-
- do_action(locdir, remname);
- }
-
- if (GotSIGINT) {
- progress ("Interrupted");
- break;
- }
-
- e->tagged = 0;
- showfile (Vis, i);
-
- }
-
- adt_disconnect();
-
- if (err)
- disp_status("Error during download");
-
- }
-
- MaskSIGINT = GotSIGINT = 0;
-
- return 0;
- }
-
- int find_string(string, progress)
- char *string;
- int (*progress) ();
- {
- FILE *fh;
- char *site;
- char *parts[10];
-
- NoFilesString = "No files found matching your pattern";
- Vis->sel = "Found files";
-
- if (!*option_get("findmethod"))
- if (setup_findmethod())
- return 1;
-
- switch (option_getnum("findmethod")) {
-
- case 0:
-
- GotComplete = GotLocal = GotRecent = 0;
-
- site = option_get("findsite");
-
- progress("Searching...");
-
- str_sitesplit(site, parts);
-
- fh = findd_fgrep(parts[1], string, 100);
-
- if (fh) {
- e_freeall();
- fgets(parsebuf, 120, fh);
- read_adt_v2(fh);
- allvisible();
- fclose(fh);
- }
- Vis->sel = "Found files";
- sort_list(Vis, &sort_dir);
-
- break;
-
- case 1:
-
- get_sitelocal();
- progress("Searching...");
- findstr(string);
- break;
-
- case 2:
-
- get_complete();
- progress("Searching...");
- findstr(string);
- break;
-
- }
-
- return 0;
- }
-
- int print_listing(width)
- int width;
- {
- ENTRY **list = Vis->list;
- FILE *f;
- char file[300];
- int i;
- long now = time(NULL);
-
- strcpy (file, glob_path( option_get("printer")));
-
- if (!*file || !(f = fopen(file, "w")))
- return 0;
-
- if (width == 1) {
-
- fputs("|File Dir Size Description\n", f);
- fputs("|------------------- ---------- ---- -----------\n", f);
-
- } else {
-
- fputs("|File Dir Size Age Description\n", f);
- fputs("|------------------- ---------- ---- --- -----------\n", f);
-
- }
-
-
- for (i = 0; i < Vis->num; i++) {
-
- if (width == 1) {
-
- fprintf(f, "%-20.20s %-10.10s %4.4s%c%-42.42s\n",
- list[i]->file,
- list[i]->dir,
- str_ksize(list[i]->size),
- list[i]->readmesize > 100 ? '+' : ' ',
- list[i]->desc);
-
- } else {
-
- fprintf(f, "%-20.20s %-10.10s %4.4s %3.3d %c%-.80s\n",
- list[i]->file,
- list[i]->dir,
- str_ksize(list[i]->size),
- (now - list[i]->time) / 86400,
- list[i]->readmesize > 100 ? '+' : ' ',
- list[i]->desc);
-
- }
- }
-
- fclose(f);
-
- return 0;
- }
-
-
- int display_remote(name, title)
- char *name;
- char *title;
- {
- TEMPFILE tfh;
- char **strings;
-
- trans_remopen(&tfh, name, "", disp_status);
-
- if (tfh.fh) {
-
- strings = read_file(tfh.fh, title);
- disp_more(strings);
- free_file(strings);
- tclose(&tfh);
-
- } else {
-
- disp_status ("Could not open remote file");
-
- }
-
- return 0;
- }
-
-
- /* =================================CURSES PACKAGE============================ */
- #ifndef NO_CURSES
-
- int debug(str)
- char *str;
- {
- move(0, 0);
- addstr(str);
- refresh();
- sleep(1);
- return 0;
- }
-
- int cur_dispinit()
- {
- initscr();
- nl();
- noecho();
- cbreak();
- return 0;
- }
-
- int cur_getchar()
- {
- int c=getchr();
- #ifdef SHOW_KEYS
- static int foo;
- char buf[20];
- sprintf(buf,"%2x",c);
- move(0, (foo+=2)%8);
- addstr(buf);
- #endif
-
- return c;
- }
-
-
- #define Y_LISTTITLE 2
- #define Y_LISTSTART 3
- #define Y_LISTEND (LINES-6)
- #define Y_INFO (LINES-5)
- #define Y_COMMAND (LINES-3)
- #define Y_STATUS (LINES-1)
-
- #define X_COMMAND 9
-
-
- int cur_helpblock(help)
- char **help;
- {
- int i, m = str_shift(str_longest(help), COLS);
-
- clear();
-
- move(0, 0);
- addstr(str_center(help[0], COLS));
-
- for (i = 0; help[i + 1]; i++) {
- move(2 + i, m);
- addstr(help[i + 1]);
- }
-
- return i;
- }
-
- char *cur_getstringat(buf, x, y)
- char *buf;
- int x, y;
- {
- char bak[300];
- int c, l = strlen(buf), p = l, i;
-
- mystrcpy(bak, buf);
-
- move(y, x);
- addstr(buf);
-
- for (;;) {
- move(y, x + p);
- refresh();
- switch (c = inp_getchr()) {
-
- case 1:
- p = 0;
- break;
-
- case 5:
- p = l;
- break;
-
- case 8: case 127:
- if (p == 0)
- break;
-
- for (i = --p; i < l; i++)
- buf[i] = buf[i + 1];
- buf[--l] = ' ';
-
- move(y, x + p);
- addstr(buf + p);
- buf[l] = 0;
- break;
-
- case 13: case 10:
- goto done;
-
- case K_RIGHT:
- if (p < l)
- p++;
- break;
-
- case K_LEFT:
- if (p > 0)
- p--;
- break;
-
- default:
- if (c < ' ' || c > 127 || l > COLS - x - 1)
- break;
-
- for (i = l; i > p; i--)
- buf[i + 1] = buf[i];
- buf[++l] = 0;
- buf[p] = c;
-
- move(y, x + p);
- addstr(buf + p);
- p++;
- break;
- }
-
- }
-
- done:
- return buf;
-
- }
-
- int OptLen;
-
- char *cur_inputstr(buf, help)
- char *buf, **help;
- {
- int x = str_shift(str_longest(help), COLS);
- int y = 3 + cur_helpblock(help);
-
- move(y, x);
- addstr("> ");
-
- return cur_getstringat(buf, x + 2, y);
- }
-
-
- char *cur_getstring(buf)
- char *buf;
- {
- int y = Y_COMMAND, x = X_COMMAND + OptLen;
- char *ret;
-
- move(y, x);
- addstr(": ");
- x += 2;
- OptLen += 2;
-
- ret = cur_getstringat(buf, x, y);
-
- OptLen = x + strlen(buf) + 1;
-
- return ret;
- }
-
- char dbuf[300];
-
- int cur_displist(list)
- LIST *list;
- {
- int i;
- char *line;
- char *t = NULL, c = 0;
-
- Window = Y_LISTEND - list->top;
-
- if (!list->num) {
- move(LINES / 2, 0);
- addstr(str_center(NoFilesString, COLS - 1));
- return 0;
- }
-
- list->offset = list->current / Window * Window;
-
- for (i = 0; i < Window; i++) {
- line = list->disp(list->list, list->offset + i, list->num, dbuf, Width);
-
- if (*line)
- move(list->top + i, list->type ? (Width - strlen(line)) / 2 : 0);
- else {
- move(list->top + i, 0);
- clrtoeol();
- }
-
- if (list->offset + i != list->current) {
- addstr(line);
- } else {
- if (list->type == 0) {
- for (t = line + 1; *t != ' '; t++);
- c = t[1];
- t[1] = 0;
- }
- standout();
- addstr(line);
- standend();
-
- if (list->type == 0) {
- t[1] = c;
- addstr(t + 1);
- }
- }
- }
-
- return 0;
- }
-
- int cur_dispfiles(list)
- LIST *list;
- {
- Window = Y_LISTEND - Y_LISTSTART;
-
- if (list == Vis) {
- move(0, 0);
- addstr(str_topline(dbuf, Width - 1, list));
- }
-
- cur_displist(list);
-
- return 0;
- }
-
-
- int cur_dispmask()
- {
- Window = Y_LISTEND - Y_LISTSTART;
-
- Vis->disp = str_entry;
- Vis->top = Y_LISTSTART;
-
- clear();
- move(Y_LISTTITLE, 0);
- addstr(str_titles(dbuf, Width - 1));
-
- cur_dispfiles(Vis);
-
- move(Y_INFO, 0);
- addstr(str_center(Vis->cmds, Width - 1));
-
- move(Y_COMMAND, 0);
- addstr("Command: ");
-
- refresh();
- return 0;
- }
-
- int cur_mark(list, on)
- LIST *list;
- int on;
- {
- char *t = NULL, *line;
-
- line = list->disp(list->list, list->current, list->num, dbuf, Width - 1);
-
- if (list->type == 0) {
- for (t = line + 1; *t != ' '; t++);
- t[1] = 0;
- }
- move(list->top + list->current - list->offset,
- list->type ? (Width - strlen(line)) / 2 : 0);
-
- if (on)
- standout();
- addstr(line);
- if (on)
- standend();
-
- if (list->type == 0)
- t[1] = ' ';
-
- return 0;
- }
-
- int cur_gomid(list)
- LIST *list;
- {
- int left = list->num - list->offset;
-
- list->current = list->offset + (left < Window ? left : Window) / 2;
- return 0;
- }
-
-
- int cur_moveto(list, pos)
- LIST *list;
- int pos;
- {
- if (!list->num)
- return 0;
-
- if (pos < 0)
- pos = 0;
-
- if (pos > list->num - 1)
- pos = list->num - 1;
-
- if (pos == list->current)
- return 0;
-
- cur_mark(list, 0);
- list->current = pos;
-
- if (pos / Window * Window == list->offset) {
-
- cur_mark(list, 1);
-
- } else {
-
- list->offset = pos / Window * Window;
- cur_dispfiles(list);
-
- }
-
- return 0;
- }
-
- int cur_listnav(list, c)
- LIST *list;
- int c;
- {
- switch (c) {
- case K_DOWN:
- case K_CTRL + 'N':
- case 'j':
- cur_moveto(list, list->current + 1);
- break;
-
- case K_UP:
- case K_CTRL + 'P':
- case 'k':
- cur_moveto(list, list->current - 1);
- break;
-
- case K_RIGHT:
- case ' ':
- case K_CTRL + 'F':
- cur_moveto(list, (list->current + Window)/Window*Window);
- break;
-
- case K_LEFT:
- case K_CTRL + 'H':
- case K_CTRL + 'B':
- case 'b':
- cur_moveto(list, (list->current - Window)/Window*Window);
- break;
-
- case K_CTRL + 'I':
- cur_moveto(list, list->current + 5);
- break;
-
- case '<':
- cur_moveto(list, 0);
- break;
-
- case '>':
- cur_moveto(list, list->num - 1);
- break;
-
- case K_CTRL + 'L':
- touchwin (stdscr);
- refresh();
- break;
-
- default:
- return 0;
-
- }
-
- return 1;
- }
-
- int cur_choice(help, list)
- char **help;
- LIST *list;
- {
- char *cmd = "Select using cursor keys, press RETURN to accept or q to cancel.";
- int c, ret = 0;
-
- list->top = 3 + cur_helpblock(help);
-
- cur_displist(list);
-
- move(Y_COMMAND, list->type ? (Width - strlen(cmd)) / 2 : 0);
- addstr(cmd);
-
- refresh();
-
- for (;;) {
- c = inp_getchr();
- if (c == 'q')
- return -1;
- if (c == 10 || c == 13) {
- ret = list->current;
- goto done;
- }
- cur_listnav(list, c);
- move(Y_COMMAND, strlen(cmd) + (list->type ? (Width - strlen(cmd)) / 2 : 0));
- refresh();
- }
-
- done:
- return ret;
- }
-
- int cur_cmdstr(string)
- char *string;
- {
- move(Y_COMMAND, X_COMMAND);
- addstr(string);
- refresh();
- OptLen = strlen(string);
-
- return 0;
- }
-
- int cur_subopt(string)
- char *string;
- {
- char buf[200], *b = buf;
- int c, i;
-
- cur_cmdstr(string);
-
- c = inp_getchr();
-
- for (i = 0; string[i] && string[i] != ' '; i++) /* view */
- *b++ = string[i];
- *b++ = ' ';
-
- for (i = strlen(string) - 1; i > 0; i--) /* a)ll */
- if (string[i] == ')' && string[i - 1] == c)
- break;
-
- if (i > 0) { /* all */
- *b++ = string[++i - 2];
- while (string[i] && string[i] != ' ')
- *b++ = string[i++];
- }
- OptLen = b - buf;
-
- while (b < buf + strlen(string)) /* blanks */
- *b++ = ' ';
- *b++ = 0;
-
- move(Y_COMMAND, X_COMMAND);
- addstr(buf);
- move(Y_COMMAND, X_COMMAND + OptLen);
- refresh();
- return c;
- }
-
- char statusbuf[300];
-
-
- int cur_statusat(string, y)
- char *string;
- int y;
- {
- int i, sh;
-
- for (i = 0; i < COLS - 1; i++)
- statusbuf[i] = ' ';
- statusbuf[i] = 0;
-
- strcpy(statusbuf + (sh = str_shift(strlen(string), COLS)), string);
- statusbuf[strlen(statusbuf)] = ' ';
-
- move(y, 0);
- addstr(statusbuf);
- move(y, sh + strlen(string));
- refresh();
-
- return 0;
- }
-
- int cur_status(string)
- char *string;
- {
- cur_statusat(string, Y_STATUS);
-
- return 0;
- }
-
- int cur_clear()
- {
- clear();
- refresh();
- return 0;
- }
-
- int cur_report(string)
- char *string;
- {
- cur_statusat(string, LINES / 2);
- return 0;
- }
-
- int cur_nosubopt()
- {
- char buf[200], *b = buf;
-
- while (OptLen--)
- *b++ = ' ';
- *b++ = 0;
- move(Y_COMMAND, X_COMMAND);
- addstr(buf);
- refresh();
- cur_status("");
- return 0;
- }
-
- int cur_more(strings)
- char **strings;
- {
- int i, c, lines, offset = 0, len = str_longest(strings);
- char buf[100], *title = *strings++;
-
- for (lines = 0; strings[lines] || lines == 0; lines++);
-
- do {
- clear();
-
- move(0, str_shift(strlen(title), len));
- standout();
- addstr(title);
- standend();
-
- for (i = 0; i < LINES - 4 && offset + i < lines; i++) {
- move(2 + i, 0);
- addstr(strings[offset + i]);
- }
-
- if (offset + i < lines)
- sprintf(buf, " --- More (%d%%), b)ack, q)uit --- ",
- (offset + i) * 100 / lines);
- else
- strcpy(buf, " --- End --- ");
-
- move(MYMIN(LINES - 1, 3 + offset + i), str_shift(strlen(buf), len));
- standout();
- addstr(buf);
- standend();
- refresh();
-
- c = inp_getchr();
- if (c == 27 || c == 'q')
- break;
- else if (c == 'b' || c == K_CTRL + 'H')
- offset = MYMAX(0, offset - (LINES - 4));
- else
- offset += LINES - 4;
-
- } while (offset < lines);
-
- return 0;
- }
-
-
- char *MainHelp[] = {
- "Aminet Download Tool Help",
- "Welcome to the Aminet Download Tool. You can select, inspect and download",
- "files here. The command keys available:",
- "",
- "cursor navigate on list",
- "blank next page (also cursor right)",
- "backspace previous page (also cursor left)",
- "tab move down five",
- "< > start and end of list",
- "",
- "d)ownload receive selected file(s) after setting options",
- "f)ind locate a file anywhere on Aminet",
- "h)elp this page",
- "o)ptions setup page",
- "p)rint create a listing on disk or printer",
- "q)uit leave, remembering this call",
- "Q)uit leave, without remembering this call",
- "r)eadme display the .readme of current file",
- "s)ort change sorting of displayed list",
- "t)ag mark/unmark current file for later download (also RETURN)",
- "T)ag mark/unmark all files",
- "v)iew select which files to show",
- "",
- "Press ? at any submenu to get help about the commands there.",
- 0
- };
-
- char *ViewHelp[] = {
- "The v)iew command",
- "This command selects which files to display in ATD. The suboptions:",
- "",
- "a)ll shows the complete list of all files on Aminet, downloading it",
- " first if necessary. No files are hidden.",
- "d)ir pick from the currently known files the ones from the directory",
- " you specify.",
- "h)ide selects one or more directory (separated by commas) that should",
- " not be shown. This info is stored in .adtrc on exit",
- "k)nown shows all currently known files, including those that are normally",
- " hidden",
- "l)imit only show the files which have the given string somewhere in their",
- " description or file name",
- "m)arked only shows the files that have previously been marked using the",
- " t)ag command",
- "n)ew shows the new files since your previous call minus the hidden ones,",
- " downloading the list if necessary",
- "s)ite shows the list of files available at the site you are currently",
- " connected to",
- "t)oggle toggle between the current list and the previously displayed one.",
- 0
- };
-
- char *SortHelp[] = {
- "The s)ort command",
- "Using this command you can select what order the files should be shown by",
- "",
- "a)ge sorts by age, showing the newest files on top",
- "A)ge like a)ge but showing the oldest files on top",
- "d)ir sorts alphabetically by directory, subsorting by name",
- "D)ir like d)ir but reverse order",
- "n)ame sorts alphabetically by file name",
- "N)ame like n)ame but reverse order",
- "s)ize sorts by file size, largest on top",
- "S)ize like s)ize, but smallst on top",
- 0
- };
-
- int cur_editvar(varname, string)
- char *varname, *string;
- {
- char buf[100];
-
- cur_status(string);
- mystrncpy(buf, option_get(varname), 99);
- cur_getstring(buf);
- option_set(varname, buf);
- return 0;
- }
-
- int cur_showfile(list, i)
- LIST *list;
- int i;
- {
- cur_moveto (list, i);
- cur_mark (list, 0);
- cur_mark (list, 1);
-
- return 0;
- }
-
- char *DownloadHelp[] = {
- "The d)ownload command",
- "This command lets you receive files from Aminet. The suboptions:",
- "",
- "a)ction select what to do after the download. Possibilities are either",
- " nothing, transfer using zmodem, or archive unpacking",
- "b)egin actually perform the download, using the current settings",
- " selected by the other keys",
- "p)ath lets you enter the destination path for the files, will be",
- " created if it does not exist",
- "q)uit do not start download, leave all undownloaded files tagged,",
- " and return to main files selection page",
- "r)eadme toggle between downloading the .readme files along with the",
- " archives and not doing so",
- "s)ubdirs toggle between putting all files in the same directory vs",
- " re-creating the Aminet directory structure",
- "v)erbose toggle between quiet and verbose download, where quiet suspends",
- " all screen output until all files have been downloaded.",
- "",
- "The current settings are displayed in the bottom line. If you want to",
- "change those settings permanently, use o)ptions d)ownload.",
- 0
- };
-
- int cur_download()
- {
- LIST *l;
- int cont = 1;
- char path[300];
-
- markedextract();
-
- l = Vis;
- Vis = Mark;
- Mark = l;
-
- Flat = option_getnum("flatdl");
- Readme = option_getnum("readmedl");
- Silent = option_getnum("silentdl");
- strcpy(Path, option_get("dlpath"));
-
- cur_dispmask();
-
- do {
- cur_status(transferstr());
- cur_cmdstr("");
-
- switch (inp_getchr()) {
- case '?':
- case 'h':
- cur_more(DownloadHelp);
- cur_dispmask();
- break;
-
- case 'p':
- cur_cmdstr("path");
- cur_editvar("dlpath", "Enter path to download files to");
- strcpy(Path, option_get("dlpath"));
- strcpy(path, Path);
- make_dirs (glob_path (path));
- cur_nosubopt();
- break;
-
- case 'b':
- cur_moveto(Vis, 0);
- get_files(cur_status, cur_showfile);
- cur_nosubopt();
- cont = 0;
- break;
-
- case 'a':
- Action = ++Action % 3;
- break;
- case 'q':
- cont = 0;
- break;
- case 'r':
- Readme = !Readme;
- break;
- case 's':
- Flat = !Flat;
- break;
- case 'v':
- Silent = !Silent;
- break;
- }
-
- } while (cont);
-
- l = Vis;
- Vis = Mark;
- Mark = l;
-
- return 0;
- }
-
- char *OptionsHelp[] = {
- "The o)ptions command",
- "Using the o)ptions command you can modify various settings of ADT. They",
- "will be saved in .adtrc when you leave ADT using the q)uit command, but",
- "not if you use Q)uit. The settings you can modify are:",
- "",
- "c)ompression lets you pick the compression type used for downloading",
- " Aminet contents files.",
- "d)ownload will pick the defaults for downloading readmes, verbose or",
- " quiet download, download path and so on",
- "f)ind lets you pick the method used for finding things on Aminet,",
- " ie. download and local search vs. using a search server",
- "m)ethod will choose the method used to transfer files, e.g. FTP",
- " mail server or local files",
- "p)rint lets you choose the format of the listings generated by ADT",
- " mostly wide vs. narrow format",
- "s)ite this lets you pick the location you want to get your files",
- " from, for example which FTP site to use", 0
- };
-
-
- char *CompressOptHelp[] = {
- "Compression type",
- "Please select the compression method to use for transmitting the Aminet",
- "index files. If you have very fast access (like local files), pick no",
- "compression, otherwise pick compress, unless you have 'gzip' in your",
- "path, which compresses even better at the same speed. Note, we're only",
- "talking about decompression here, its only the choice between different",
- "versions of the index files in fact.", 0
- }, *CompressList[] = {
- " none ",
- "compress",
- " gzip ", 0
- };
-
- char *FlatOptHelp[] = {
- "Flat or tree download",
- "Please choose whether to put all downloaded files in the same",
- "directory or to create the correct subdirectory as on Aminet ",
- "for each file downloaded", 0
- }, *FlatDlList[] = {
- "subdir (create subdirs)",
- "flat (same directory)", 0
- };
-
- char *ReadmeOptHelp[] = {
- "Readme download",
- "Please choose whether or not to download the .readme files",
- "along with the archives", 0
- }, *ReadmeDlList[] = {
- "download archives only",
- "download .readme files too", 0
- };
-
- char *QuietOptHelp[] = {
- "Silent download",
- "Please choose wheter or not to perform transfers quietly. If you turn on",
- "quiet mode, no screen output happens until the download is completey over.",
- "This allows you to interrupt ADT using CTRL-Z and put it in the background",
- "using 'bg' to download quietly in the background", 0
- }, *QuietDlList[] = {
- "give progress reports",
- "download quietly", 0
- };
-
- char *FindSitesHelp[] = {
- "Find site",
- "Here you can pick the find server to use for your queries. Feel free to",
- "them all and choose the fastest. All find servers have the complete list",
- "of all Aminet files online", 0
- };
-
- char FindString[120];
-
- int cur_cmdkeys(c)
- int c;
- {
- char buf[200];
- SORT *sorttype;
- int noredraw = 0, width = 0;
-
- buf[0] = 0;
-
- switch (c) {
-
- case 'd':
- if (Vis->num)
- cur_download();
- break;
-
- case 'f':
- cur_cmdstr("find");
- cur_status("(Use 'adt -f <keyword>' to start finds from the command line)");
- FindString[0] = 0;
- cur_getstring(FindString);
- if (*FindString)
- find_string(FindString, cur_status);
- break;
-
- case 'o':
- options:
- switch (cur_subopt("options c)ompression d)ownload f)ind m)ethod s)ite")) {
- case '?':
- case 'h':
- cur_more(OptionsHelp);
- cur_dispmask();
- goto options;
-
- case 'c':
- setup_enumed(CompressOptHelp, CompressList, "compress");
- break;
-
- case 'd':
- cur_editvar("dlpath", "Enter path to download files to"),
- cur_editvar("send", "Enter command to use for sending files, eg. 'sz'");
- setup_enumed(FlatOptHelp, FlatDlList, "flatdl");
- setup_enumed(ReadmeOptHelp, ReadmeDlList, "readmedl");
- setup_enumed(QuietOptHelp, QuietDlList, "quietdl");
- break;
-
- case 'f':
- setup_findmethod();
- break;
-
- case 'm':
- trans_close();
- e_freeall();
- setup_method();
- get_recent();
- newvisible();
- NoFilesString = "Use v)iew or f)ind to get files to the display";
- break;
-
- case 's':
- if (trans_options())
- break;
- if (CdRom) {
- get_sitelocal();
- allvisible();
- } else {
- get_recent();
- newvisible();
- }
- break;
-
- default:
- noredraw = 1;
- }
- cur_nosubopt();
-
- break;
-
- case 'p':
- cur_status("Narrow format fits 80 columns, wide format format 132 columns");
- switch (cur_subopt("print n)arrow w)ide")) {
- case 'n':
- width = 1;
- break;
- case 'w':
- width = 2;
- break;
- }
- if (width) {
- cur_editvar("printer", "Enter the file to print the visible files to");
- print_listing(width);
- }
- cur_nosubopt();
- noredraw = 1;
- break;
-
- case 'q':
- cur_cmdstr("quit (and save config file)");
- option_save(ConfigFile);
- exit_adt(0);
- break;
-
- case 'Q':
- cur_cmdstr("quit (without saving config file)");
- exit_adt(0);
- break;
-
- case 'v':
- view:
- switch (cur_subopt("view a)ll d)ir h)ide k)nown l)imit m)arked n)ew s)ite t)oggle")) {
- case '?':
- cur_more(ViewHelp);
- cur_dispmask();
- goto view;
-
- case 'a':
- if (!GotComplete) {
- get_complete();
- allvisible();
- }
- break;
-
- case 'd':
- cur_status("Select directory to show exclusively");
- dirvisible(cur_getstring(buf));
- cur_status("");
- break;
-
- case 'h':
- cur_editvar("hide", "Enter directories to hide permanently");
- invisible();
- break;
-
- case 'k':
- allvisible();
- break;
-
- case 'l':
- cur_status("Enter string to match in currently displayed descriptions");
- strlimit(cur_getstring(buf));
- cur_status("");
- break;
-
- case 'm':
- markedvisible();
- break;
-
- case 'n':
- get_recent();
- newvisible();
- break;
-
- case 's':
- if (!GotLocal) {
- get_sitelocal();
- cur_clear();
- cur_report("Sorting...");
- allvisible();
- }
- break;
-
- case 't':
- togglevisible();
- break;
-
- default:
- noredraw = 1;
- }
-
- cur_nosubopt();
- break;
-
- case 'r':
- if (Vis->num) {
- ENTRY *e=Vis->list[Vis->current];
-
- strcpy(buf, e->dir);
- tackon(buf, get_readme(e));
- adt_connect (disp_status, e->status & 1);
- display_remote(buf, get_readme(e));
- adt_disconnect();
- }
- break;
-
- case 's':
- sorttype = 0;
- sort:
- switch (cur_subopt("sort a)ge d)ir n)ame s)ize")) {
- case '?':
- cur_more(SortHelp);
- cur_dispmask();
- goto sort;
- case 'a':
- sorttype = &sort_age;
- break;
- case 'd':
- sorttype = &sort_dir;
- break;
- case 'n':
- sorttype = &sort_name;
- break;
- case 's':
- sorttype = &sort_size;
- break;
- case 'A':
- sorttype = &sort_rage;
- break;
- case 'D':
- sorttype = &sort_rdir;
- break;
- case 'N':
- sorttype = &sort_rname;
- break;
- case 'S':
- sorttype = &sort_rsize;
- break;
- }
- if (sorttype) {
- cur_status("Sorting...");
- sort_list(Vis, sorttype);
- cur_dispfiles(Vis);
- cur_status("");
- }
- noredraw = 1;
- cur_nosubopt();
- break;
-
- case 'h':
- case '?':
- cur_more(MainHelp);
- break;
-
- case 't':
- case 13: case 10:
- noredraw = 1;
- if (!Vis->num)
- break;
- cur_mark(Vis, 0);
- tagcurrent();
- cur_mark(Vis, 1);
- cur_moveto(Vis, Vis->current + 1);
- break;
-
- case 'T':
- tagall();
- break;
-
- default:
- noredraw = 1;
-
- }
-
- if (!noredraw)
- cur_dispmask();
-
- return 0;
- }
-
-
-
- int cur_mainloop()
- {
- int c;
-
- refresh();
- cur_dispmask();
- refresh();
-
- while ((c = inp_getchr())) {
- cur_listnav(Vis, c);
- cur_cmdkeys(c);
- move(Y_COMMAND, X_COMMAND);
- refresh();
- }
-
- return 0;
- }
-
- int cur_cleanup()
- {
- nocbreak();
- echo();
- endwin();
- #ifndef AMIGA
- puts("");
- #endif
- return 0;
- }
-
- int cur_getcmd()
- {
- return getchr();
- }
-
-
- int cur_confirm(strings, retry)
- char **strings;
- int retry;
- {
- int i, j, m = str_shift(str_longest(strings), COLS);
-
- for (i = 0; strings[i]; i++);
-
- clear();
-
- for (j = 0; j < i; j++) {
- move((LINES - i - 2) / 2 + j, m);
- addstr(strings[j]);
- }
-
- move((LINES - i - 2) / 2 + j + 1, m + str_longest(strings) - strlen("Press any key"));
- addstr("Press any key");
-
- refresh();
- inp_getchr();
-
- return 0;
- }
-
- int cur_refresh()
- {
- refresh();
-
- return 0;
- }
-
- #endif
-
- /*---------------------------------main program------------------------------*/
- int init_vars()
- {
- char *d, *t;
- int i;
-
- mystrcpy(HomeDir, (t = (char *) getenv("HOME")) ? t : "");
-
- if (*HomeDir) {
- d = UserName;
- for (i = 0; HomeDir[i]; i++)
- if (HomeDir[i] == '/')
- d = UserName;
- else
- *d++ = HomeDir[i];
- *d++ = 0;
- }
- #ifdef AMIGA
- mystrcpy(ConfigFile, "S:.adtrc");
- #else
- mystrcpy(ConfigFile, HomeDir);
- tackon(ConfigFile, ".adtrc");
- #endif
-
- Alt->sort = Vis->sel = "";
- Alt->sort = Vis->sort = "";
- Alt->cmds = Vis->cmds = "d)ownload f)ind h)elp o)ptions p)rint q)uit r)eadme s)ort t)ag v)iew";
-
- Mark->sel = "Files to be downloaded";
- Mark->sort = "";
- Mark->cmds = "a)ction b)egin p)ath q)uit r)eadmes s)ubdirs v)erbose";
-
- return 0;
- }
-
- char recentbuf[100];
- char *FirstConnectHelp[] = {
- "This seems to be the first time you connect. You'll be seeing the last",
- "14 days' uploads now. Next time you connect, all the files that were",
- "uploaded since this connection will be shown.", 0
- };
-
- char *LongAgoHelp[] = {
- "Your last connection was more than 14 days ago, but you'll only be seeing",
- "the last 14 days' uploads. If you want to see everything, use v)iew a)ll",
- "and filter accordingly.", 0
- };
-
- int get_list(title, name)
- char *title, *name;
- {
- TEMPFILE tfh;
- char buf[250];
- char *packer = "";
- long amotd = 0, lmotd = 0, sites = 0;
-
- e_freeall();
-
- if (option_getnum("compress") == 1)
- packer = ".Z";
-
- if (option_getnum("compress") == 2)
- packer = ".gz";
-
- sprintf(buf, "info/adt/%s", name);
-
- disp_clear();
- disp_report(title);
-
- adt_connect(disp_report, STATUS_LOCAL);
-
- NoFilesString = "Could not download index file";
- trans_remopen(&tfh, buf, packer, disp_report);
-
- if (tfh.fh) {
-
- disp_report("Reading index");
- do {
- *parsebuf = 0;
- fgets(parsebuf, PBUFSIZE, tfh.fh);
- if (!mystrncmp(parsebuf, "#amotd=", 7))
- amotd = p_atoi(parsebuf + 7);
- if (!mystrncmp(parsebuf, "#lmotd=", 7))
- lmotd = p_atoi(parsebuf + 7);
- if (!mystrncmp(parsebuf, "#sites=", 7))
- sites = p_atoi(parsebuf + 7);
-
- } while (*parsebuf == '#');
-
- read_adt_v2(tfh.fh);
- tclose(&tfh);
-
- }
-
- if (!option_getnum("nomotd")) {
- if (amotd > option_getnum("amotd")) {
- disp_clear();
- disp_report("Retrieving new Aminet message of the day");
- display_remote("info/adt/aminet-motd","Aminet message of the day");
- option_setnum("amotd", amotd);
- }
- if (lmotd > option_getnum("lmotd")) {
- disp_clear();
- disp_report("Retrieving new local message of the day");
- display_remote("info/adt/local-motd","Mirror message of the day");
- option_setnum("lmotd", lmotd);
- }
- }
- if (sites > option_getnum("sites")) {
- disp_clear();
- disp_report("Updating mirror list");
- trans_remopen(&tfh, "info/adt/sites", "", disp_status);
- if (tfh.fh) {
- option_loadfh(tfh.fh);
- tclose(&tfh);
- }
- option_setnum("sites", sites);
- }
-
- adt_disconnect();
-
- return 0;
- }
-
- int get_complete()
- {
- if (!GotComplete)
- get_list("Downloading the list of all Aminet files", "ADT_AMINET");
-
- GotComplete = GotLocal = GotRecent = 1;
-
- return 0;
- }
-
- int get_sitelocal()
- {
- if (!GotLocal)
- get_list("Downloading the list of files on this site", "ADT_LOCAL");
-
- GotLocal = GotRecent = 1;
-
- return 0;
- }
-
-
- int get_recent()
- {
- long age;
-
- if (GotRecent)
- return 0;
-
- GotRecent = 1;
-
- LastCall = myatoi(option_get("newest"));
- age = time(NULL) - LastCall;
-
- if (LastCall == 0) {
- disp_confirm(FirstConnectHelp, 0);
- get_list("Downloading the list of new files", "ADT_RECENT_14");
- } else if (age < 7 * 86400) {
- get_list("Downloading the list of new files", "ADT_RECENT_7");
- } else if (age < 14 * 86400) {
- get_list("Downloading the list of new files", "ADT_RECENT_14");
- } else {
- disp_confirm(LongAgoHelp, 0);
- get_list("Downloading the list of new files", "ADT_RECENT_14");
- }
-
- if (newesttime() > option_getnum("newest"))
- option_setnum("newest", newesttime());
-
- return 0;
- }
-
- int init_display()
- {
- disp_init = cur_dispinit;
- disp_getchar = cur_getchar;
- disp_cleanup = cur_cleanup;
- disp_choice = cur_choice;
- disp_mainloop = cur_mainloop;
- disp_report = cur_report;
- disp_status = cur_status;
- disp_confirm = cur_confirm;
- disp_more = cur_more;
- disp_inputstr = cur_inputstr;
- disp_clear = cur_clear;
- disp_refresh = cur_refresh;
-
- disp_init();
-
- #ifdef SIGINT
- signal (SIGINT, adt_breakcheck);
- #endif
-
- return 0;
- }
-
-
- int init_config()
- {
- if (option_load(ConfigFile) || trans_init()) {
-
- InitialSetup = 1; /* was 1 originally, but must be 0 to use predefined options */
- setup_method();
- InitialSetup = 0;
- option_save(ConfigFile);
-
- }
- return 0;
- }
-
- int show_usage()
- {
- puts("Usage: adt (show new files since last call)");
- puts(" adt -f pattern (find pattern using configured method)");
- puts(" adt -l (show files local to configured site)");
- puts(" adt -n (don't connect)");
- exit_adt(0);
- return 0;
- }
-
- int parse_commandline(argc, argv)
- int argc;
- char *argv[];
- {
- if (argc <= 1) {
- if (CdRom) {
- get_sitelocal();
- allvisible();
- } else {
- get_recent();
- newvisible();
- }
- return 0;
- }
- if (argv[1][0] != '-' || !argv[1][1] || argv[1][2])
- show_usage();
-
- switch (argv[1][1]) {
- case 'f':
- if (argc != 3)
- show_usage();
- find_string(argv[2], cur_report);
- break;
-
- case 'l':
- if (argc != 2)
- show_usage();
- get_sitelocal();
- newvisible();
- break;
-
- case 'n':
- if (argc != 2)
- show_usage();
- NoFilesString="Use o)ptions to connect to a service/site";
- break;
-
- default:
- show_usage();
- }
-
- return 0;
- }
-
-
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- init_vars();
- init_display();
- init_config();
-
- parse_commandline(argc, argv);
- disp_mainloop();
-
- exit_adt(0);
- return 0;
- }
-
- TRANSFER TransferTypes[] =
- {
- #ifndef NO_BUILTIN_FTP
- "bftp", "Builtin FTP: Use internal ftp routines to download files ", bftp_init,
- #endif
- #ifndef NO_EXTERNAL_FTP
- "ftp", "External FTP: Use the 'ftp' program to download files ", xftp_init,
- #endif
- "local", "Local files : Access a local, updated Aminet file collection ", local_init,
- "cdrom", "CD-ROM : Access an Aminet CD-ROM or non-updated files ", local_init,
- 0, 0, 0
- };
-
-
- /* to delete: ftp.log, pad, recent, short */
-
-